/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ifpb.pod.servidor.precistence;

import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

/**
 *
 * @author Diogenes
 */
public class DAOGenericImpl implements DAO {

    private EntityManagerFactory factory;
    private EntityManager em;
    private static DAOGenericImpl instance = null;

    private DAOGenericImpl() {
    }

    public static DAOGenericImpl getInstance() {
        if (instance == null) {
            instance = new DAOGenericImpl();
        }
        return instance;
    }

    public Boolean salvar(Object object) {
       open();
        try {
            this.em.getTransaction().begin();
            this.em.persist(object);
             System.out.println("sou true");
            this.em.getTransaction().commit();
           
            return Boolean.TRUE;
        } catch (Exception ex) {
            em.getTransaction().rollback();
            ex.printStackTrace();
            System.out.println("sou false");
            return Boolean.FALSE;
        } finally {
//            close();
        }
    }

    public Boolean remover(Object object) {
        open();
        try {
            this.em.getTransaction().begin();
            this.em.remove(object);
            this.em.getTransaction().commit();
            return Boolean.TRUE;
        } catch (Exception ex) {
            em.getTransaction().rollback();
            ex.printStackTrace();
            return Boolean.FALSE;
        } finally {
//            close();
        }
    }

    public Boolean atualizar(Object object) {
        open();
        try {
            this.em.getTransaction().begin();
            this.em.merge(object);
            this.em.getTransaction().commit();
            return Boolean.TRUE;
        } catch (Exception ex) {
            em.getTransaction().rollback();
            ex.printStackTrace();
            return Boolean.FALSE;
        } finally {
//            close();
        }
    }

    public <T> T buscar(Class<T> classe, Object id) {
        open();
        try {
            return this.em.find(classe, id);
        } finally {
//            close();
        }
    }

    public <T> List<T> buscarTodos(Class<T> classe) {
        open();
        try {
            return this.em.createQuery("from " + classe.getSimpleName()).getResultList();
        } finally {
//            close();
        }
    }

    public <T> T executeSingleQuery(Class<T> classe, String namedQuery, Map<Integer, Object> parametros) {
        open();
        try {
            Query q = this.em.createNamedQuery(namedQuery);
            for (Integer key : parametros.keySet()) {
                q.setParameter(key, parametros.get(key));
            }
            return (T) q.getSingleResult();
        } catch (Exception ex) {

            return null;
        } finally {
//            close();
        }
    }

    public <T> List<T> executeMultiplyQuery(Class<T> classe, String namedQuery, Map<Integer, Object> parametros) {
        open();
        try {
            Query q = this.em.createNamedQuery(namedQuery);
            for (Integer key : parametros.keySet()) {
                q.setParameter(key, parametros.get(key));
            }
            return (List<T>) q.getResultList();
        } catch (Exception ex) {

            return null;
        } finally {
//            close();
        }
    }



    private void open() {
        if (this.factory == null || !this.factory.isOpen()) {        
            this.factory = Persistence.createEntityManagerFactory("TookPU");
        }
        if (this.em == null || !this.em.isOpen()) {
            this.em = factory.createEntityManager();
        }
    }

    private void close() {
        if (this.factory != null || this.factory.isOpen()) {
            this.factory.close();
        }
        if (this.em != null || this.em.isOpen()) {
            this.em.close();
        }
    }
}
